<?php
class CF_Auth extends CF_Component
{
	protected static $_instance;
	
	protected $_storage;
	protected $_defaultStorageClass = 'CF_Auth_Storage_Session';
	
	protected function __construct(){}
	protected function __clone(){}
	
	/**
	 * @return CF_Auth self
	 */
	public static function getInstance()
	{
		if(null == self::$_instance){
			self::$_instance = new self();
			
			self::$_instance->addEvents(
				'beforeauthenticate',
				'authenticate'
			);
		}
		return self::$_instance;
	}
	
	/**
	 * @return CF_Auth_Storage_Interface
	 */
	public function getStorage()
	{
		if(null == $this->_storage){
			$this->_storage = new $this->_defaultStorageClass;
		}
		return $this->_storage;
	}
	
	/**
	 * 
	 * @param CF_Auth_Storage_Interface $storage
	 * @return CF_Auth $this
	 */
	public function setStorage(CF_Auth_Storage_Interface $storage)
	{
		$this->_storage = $storage;
		return $this;
	}
	
	/**
	 * 
	 * @param CF_Auth_Adapter_Abstract $adapter
	 */
	public function authenticate(CF_Auth_Adapter_Abstract $adapter)
	{
		# notify before authenticate event
		if(CF_Observable::VALUE_RETURN === $this->fireEvent('beforeauthenticate', array($this, $adapter))) return;
		
		# clear storage data
		$this->getStorage()->clear();
		
		# get authenticate from adapter
		$result = $adapter->authenticate();
		
		if(!empty($result)){
			$this->getStorage()->setData($result);
		}
		
		# notify authenticate event
		$this->fireEvent('authenticate', array($this, $result));
		
		return $this;
	}
	
	/**
	 * @return boolean
	 */
	public function has()
	{
		return $this->getStorage()->has();
	}
	
	/**
	 * @return mixed
	 */
	public function getData()
	{
		return $this->getStorage()->getData();
	}
}